#include "TimeServerConfig.hpp"
#include "cybertron/core/JsonReader.hpp"
#pragma warning(disable:4244)
TimeServerConfig::TimeServerConfig()
{
	clear();
}

TimeServerConfig::~TimeServerConfig()
{
	clear();
}

bool TimeServerConfig::loadFromString(nlohmann::json& nodeJsonRoot)
{
	clear();

	//nlohmann::json worldJsonRoot;
	//if (!JsonReader::loadString(worldJsonRoot, worldConfig))
	//{
	//	return false;
	//}
	//if (cybertron::JsonReader::hasValue(worldJsonRoot, "taskuuid"))
	//	mTaskUUID = cybertron::JsonReader::getString(worldJsonRoot, "taskuuid");
	//if (cybertron::JsonReader::hasValue(worldJsonRoot, "speed"))
	//	mSpeed = cybertron::JsonReader::getDouble(worldJsonRoot, "speed");
	//if (mSpeed <= 0)
	mSpeed = 1.0;

	//logInfo("Node Time Config Content:%s", workJson.c_str());
	//nlohmann::json nodeJsonRoot;


	//if (!JsonReader::loadString(nodeJsonRoot, workJson))
	//{
	//	return false;
	//}

	mTimeoutMs = JsonReader::getInt(nodeJsonRoot, "timeoutMs");
	if (mTimeoutMs <= 0)
	{
		mTimeoutMs = DefaultTimeoutMs;
	}

	mFps = JsonReader::getInt(nodeJsonRoot, "hz");
	if (mFps <= 0)
	{
		mFps = DefaultFps;
	}

	mNumBuiltinIds = JsonReader::getInt(nodeJsonRoot, "numBuiltinIds");
	if (mNumBuiltinIds < 0)
	{
		mNumBuiltinIds = 0;
	}

	mTimeLoopTimeoutMs = JsonReader::hasValue(nodeJsonRoot, "timeLoopTimeoutMs") ?
		JsonReader::getInt(nodeJsonRoot, "timeLoopTimeoutMs") :
		DefaultTimeLoopTimeoutMs;

	if (JsonReader::hasValue(nodeJsonRoot, "replayFile"))
		mReplayFile = JsonReader::getString(nodeJsonRoot, "replayFile");

	if (JsonReader::hasValue(nodeJsonRoot, "recordFile")) {
		
		mRecordFile = JsonReader::getString(nodeJsonRoot, "recordFile");
		//mReplayFile = mRecordFile;
	}
	

	if (JsonReader::hasValue(nodeJsonRoot, "syncNodes"))
	{
		auto syncNodeL = cybertron::JsonReader::getChild(nodeJsonRoot, "syncNodes");
		for (size_t i = 0; i < syncNodeL.size(); i++)
		{
			auto syncNode = syncNodeL[i];

			SyncNode sn{ cybertron::JsonReader::getString(syncNode, "imageUuid") ,
				cybertron::JsonReader::getInt(syncNode, "instanceId") , false };
			logInfo("SyncNode: %s:%d", sn.imageName.c_str(), sn.imageInstanceId);
			// Check whether node in network
			for (auto it = mNetWorkNodes.begin(); it != mNetWorkNodes.end(); it++)
			{
				if ((*it).instanceid() == sn.imageInstanceId)
					sn.bInNetwork = true;
			}
			mSyncNodes.push_back(sn);
		}
	}

	return true;
}

void TimeServerConfig::clear()
{
	mTaskUUID = std::string();
	mTimeoutMs = 0;
	mSpeed = 1.0f;
	mNumBuiltinIds = 0;
	mFps = DefaultFps;
	mTimeLoopTimeoutMs = DefaultTimeLoopTimeoutMs;
	mSyncNodes.clear();
}

std::string TimeServerConfig::getTaskUUID() const
{
	return mTaskUUID;
}

int TimeServerConfig::getTimeoutMs() const
{
	return mTimeoutMs;
}

float TimeServerConfig::getSpeed() const
{
	return mSpeed;
}

int TimeServerConfig::getFps() const
{
	return mFps;
}

int TimeServerConfig::getNumBuiltinIds() const
{
	return mNumBuiltinIds;
}

int TimeServerConfig::getTimeLoopTimeoutMs() const
{
	return mTimeLoopTimeoutMs;
}

std::string TimeServerConfig::getRecordFile() const
{
	return mRecordFile;
}

std::string TimeServerConfig::getReplayFile() const
{
	return mReplayFile;
}

std::vector<TimeServerConfig::SyncNode> &TimeServerConfig::getSyncNodes()
{
	return mSyncNodes;
}

void TimeServerConfig::addNetWorkNode(Timer::NodeDescription node)
{
	// Check whether node in network
	mNetWorkNodes.push_back(node);
	for (auto it = mSyncNodes.begin(); it != mSyncNodes.end(); it++)
	{
		if ((*it).imageInstanceId == node.instanceid())
			(*it).bInNetwork = true;
	}
}

std::vector<Timer::NodeDescription> &TimeServerConfig::getNetWorkNodes()
{
	return mNetWorkNodes;
}
